/*
 * Copyright 2016 jeasonlzy(廖子尧)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.haoniu.zzx.app_ts.http;

import com.google.gson.stream.JsonReader;
import com.haoniu.zzx.app_ts.utils.L;
import com.lzy.okgo.convert.Converter;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * ================================================
 * 作    者：jeasonlzy（廖子尧）Github地址：https://github.com/jeasonlzy
 * 版    本：1.0
 * 创建日期：16/9/11
 * 描    述：
 * 修订历史：
 * ================================================
 */
public class JsonConvert<T> implements Converter<T> {

    private Type type;
    private Class<T> clazz;

    public JsonConvert() {
    }

    public JsonConvert(Type type) {
        this.type = type;
    }

    public JsonConvert(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 该方法是子线程处理，不能做ui相关的工作
     * 主要作用是解析网络返回的 response 对象，生成onSuccess回调中需要的数据对象
     * 这里的解析工作不同的业务逻辑基本都不一样,所以需要自己实现,以下给出的时模板代码,实际使用根据需要修改
     */
    @Override
    public T convertResponse(Response response) throws Throwable {
        if (type == null) {
            if (clazz == null) {
                // 如果没有通过构造函数传进来，就自动解析父类泛型的真实类型（有局限性，继承后就无法解析到）
                Type genType = getClass().getGenericSuperclass();
                type = ((ParameterizedType) genType).getActualTypeArguments()[0];
            } else {
                return parseClass(response, clazz);
            }
        }

        if (type instanceof ParameterizedType) {
            return parseParameterizedType(response, (ParameterizedType) type);
        } else if (type instanceof Class) {
            return parseClass(response, (Class<?>) type);
        } else {
            return parseType(response, type);
        }
    }

    private T parseClass(Response response, Class<?> rawType) throws Exception {
        if (rawType == null) return null;
        ResponseBody body = response.body();
        if (body == null) return null;
        String str = body.string();
        L.d("返回的数据:" + str);
        if (rawType == String.class) {
            ServerData serverData = com.alibaba.fastjson.JSONObject.parseObject(str, ServerData.class);
            if (serverData != null) {
                if (serverData.getCode() == 1) {
                    return (T) serverData.getData();
                } else {//
                    throw new IllegalStateException(serverData.getMessge());
                }
            } else {
                throw new IllegalStateException("请求失败，返回数据为空！");
            }
        } else if (rawType == JSONObject.class) {
            //noinspection unchecked
            return (T) new JSONObject(str);
        } else if (rawType == JSONArray.class) {
            //noinspection unchecked
            return (T) new JSONArray(body.string());
        } else {
            ServerData serverData = com.alibaba.fastjson.JSONObject.parseObject(str, ServerData.class);
            if (serverData != null) {
                if (serverData.getCode() == 1) {
                    T t = (T) com.alibaba.fastjson.JSONObject.parseObject(serverData.getData(), rawType);
                    return t;
                } else {//
                    throw new IllegalStateException(serverData.getMessge());
                }
            } else {
                throw new IllegalStateException("请求失败，返回数据为空！");
            }
        }
    }

    private T parseType(Response response, Type type) throws Exception {
        if (type == null) return null;
        ResponseBody body = response.body();
        if (body == null) return null;
        JsonReader jsonReader = new JsonReader(body.charStream());
        // 泛型格式如下： new JsonCallback<任意JavaBean>(this)
        T t = Convert.fromJson(jsonReader, type);
        response.close();
        return t;
    }

    private T parseParameterizedType(Response response, ParameterizedType type) throws Exception {
        if (type == null) return null;
        ResponseBody body = response.body();
        if (body == null) return null;
        JsonReader jsonReader = new JsonReader(body.charStream());
        Type rawType = type.getRawType();                     // 泛型的实际类型
        Type typeArgument = type.getActualTypeArguments()[0]; // 泛型的参数
        if (rawType != ServerData.class) {
            ServerData serverData = com.alibaba.fastjson.JSONObject.parseObject(body.string(), ServerData.class);
            response.close();
            int code = serverData.getCode();
            if (code == 1) {
                T t = Convert.fromJson(serverData.getData(), type);
                return t;
            } else {
                throw new IllegalStateException(serverData.getMessge());
            }
        } else {
            if (typeArgument == Void.class) {
                SimpleResponse simpleResponse = Convert.fromJson(jsonReader, SimpleResponse.class);
                response.close();
                return (T) simpleResponse.toLzyResponse();
            } else {
                ServerData serverData = Convert.fromJson(jsonReader, type);
                response.close();
                if (serverData.getCode() == 1) {
                    return (T) serverData.getData();
                } else {//
                    throw new IllegalStateException(serverData.getMessge());
                }
            }
        }
    }
}
